import * as THREE from "three";
import Bus from "./eventBus";

// 创建场景
const scene = new THREE.Scene();

// 创建相机
const camera = new THREE.PerspectiveCamera(45, window.innerWidth / 400, 0.1, 1000);
camera.position.z = 5;

// 创建渲染器
const renderer = new THREE.WebGLRenderer({
    preserveDrawingBuffer: true
});
renderer.setClearColor("#fff");
renderer.setSize(window.innerWidth, 400);
document.body.appendChild(renderer.domElement);

// 保存图片
Bus.subscribe((item) => {
    if (item === true) {
        const link = document.createElement("a");
        const canvas = renderer.domElement;
        link.href = canvas.toDataURL("image/png");
        link.download = "threejs.jpg";
        link.click();

    }
})

// 用于控制线条长度的比例因子，可根据需求调整
const lengthFactor = 1;

// 存储所有线条相关信息的数组
const linesData = [];

// 在全局作用域或者合适的闭包作用域中定义一个变量来存储keyup事件监听器函数
let keyupEventListener;

// 处理移动端触摸事件的函数
function handleTouchStart(event) {

    const touch = event.touches[0];
    if (touch.clientY < 400) {
        event.preventDefault();
        event.stopPropagation();

        // 将触摸点坐标转换为归一化设备坐标（NDC）
        const x = (touch.clientX / window.innerWidth) * 2 - 1;
        const y = - (touch.clientY / 400) * 2 + 1;

        // 将归一化设备坐标转换为三维世界坐标
        const vector = new THREE.Vector3(x, y, 0.5);
        vector.unproject(camera);

        const dir = vector.sub(camera.position).normalize();
        const distance = - camera.position.z / dir.z;
        const point = camera.position.clone().add(dir.multiplyScalar(distance));

        // 将当前触摸点坐标添加到存储数组
        addTouchPointToArray(point);
    } else {
        let divBox = document.querySelectorAll(".lineBox");
        let name = "";
        if (divBox) {
            divBox.forEach((item) => {
                item.addEventListener("click", () => {
                    name = item.innerHTML;
                    // 获取场景中对应的对象，添加错误处理
                    let sname = getSceneObjectByName(name);
                    if (sname) {
                        if (keyupEventListener) {
                            document.removeEventListener('keyup', keyupEventListener);
                        }
                        // 重新绑定keyup事件监听器并获取输入值来更新线条
                        bindKeyupEventListener(sname);
                    } else {
                        console.error(`未找到名称为${name}的场景对象`);
                    }
                });
            });
        }
    }
}

// 添加触摸点坐标到数组的函数，并在满足条件时创建连接线条
function addTouchPointToArray(point) {
    const touchedPoints = getTouchedPoints();
    const newPoints = [...touchedPoints, point];
    setTouchedPoints(newPoints);

    // 如果存储了两个及以上的点位，就创建横线连接最新的两个点位
    if (newPoints.length >= 2) {
        createConnectingLine(newPoints[newPoints.length - 2], newPoints[newPoints.length - 1]);
    }
}

// 获取存储的触摸点坐标数组的函数
function getTouchedPoints() {
    return window.lastTwoPoints || [];
}

// 设置存储的触摸点坐标数组的函数
function setTouchedPoints(points) {
    window.lastTwoPoints = points;
}

// 根据名称获取场景对象的函数，添加错误处理
function getSceneObjectByName(name) {
    const sceneObject = scene.getObjectByName(name);
    if (!sceneObject) {
        console.error(`未在场景中找到名称为${name}的对象`);
    }
    return sceneObject;
}

// 用于生成线条名称和计数的对象，避免全局变量
const lineCounter = { count: 0 };

// 根据两个点位创建横线的函数
function createConnectingLine(point1, point2) {
    lineCounter.count += 1;

    if (lineCounter.count % 5 != 0) {
        // 通过两个点的坐标创建新的点位
        const direction = new THREE.Vector3().subVectors(point2, point1);
        const newPoint2 = point1.clone().add(direction.multiplyScalar(lengthFactor));

        // 定义线的几何形状（使用THREE.BufferGeometry）
        const positions = new Float32Array([
            point1.x, point1.y, point1.z,
            newPoint2.x, newPoint2.y, newPoint2.z
        ]);

        const lineGeometry = new THREE.BufferGeometry();
        lineGeometry.setAttribute('position', new THREE.BufferAttribute(positions, 3));

        // 定义线的材质
        const lineMaterial = new THREE.LineBasicMaterial({
            color: 0xff0000,
            linewidth: 2
        });

        // 创建线对象并添加到场景
        const line = new THREE.Line(lineGeometry, lineMaterial);
        line.name = `线条${lineCounter.count}`;

        // 将线条相关信息添加到linesData数组
        const newLineData = {
            name: line.name,
            startPoint: point1,
            endPoint: newPoint2,
            nextLine: null,
            prevLine: null
        };
        linesData.push(newLineData);
        localStorage.setItem('linesData1', JSON.stringify(linesData));
        let newDiv = document.createElement("div");
        newDiv.className = "lineBox";
        newDiv.style.width = "100px";
        newDiv.style.height = "30px";
        newDiv.style["line-height"] = "30px";
        newDiv.style.float = "left";
        newDiv.innerHTML = `线条${lineCounter.count}`;
        document.body.appendChild(newDiv);

        scene.add(line);

        return line;
    }
}

// 更新线条终点坐标并重新渲染线条的函数
function updateLineEndPoint(sname, num) {
    // 重新创建startPoint作为THREE.Vector3
    let startPoint = new THREE.Vector3().fromArray(sname.geometry.attributes.position.array.slice(0, 3));
    // 重新创建endPoint作为THREE.Vector3
    let endPoint = new THREE.Vector3().fromArray(sname.geometry.attributes.position.array.slice(3, 6));

    const direction = new THREE.Vector3().subVectors(endPoint, startPoint).normalize();

    // 根据新的长度和方向向量计算新的终点坐标
    const newEndPoint = startPoint.clone().add(direction.multiplyScalar(Number(num)));

    // 更新线条几何体的坐标
    let vertices = new Float32Array([
        startPoint.x, startPoint.y, startPoint.z,
        newEndPoint.x, newEndPoint.y, newEndPoint.z
    ]);
    let num1 = sname.name.match(/\d+/g)[0];

    // 获取当前线条在linesData中的索引
    let currentLineIndex = linesData.findIndex((line) => line.name === sname.name);

    // 更新当前线条的终点坐标以及相关触摸点数组（假设仍需更新触摸点数组）
    const touchedPoints = getTouchedPoints();
    touchedPoints[num1 - 1] = startPoint;
    touchedPoints[num1] = newEndPoint;
    setTouchedPoints(touchedPoints);

    sname.geometry.setAttribute('position', new THREE.BufferAttribute(vertices, 3));

    // 更新与之相连的下一个线条的起始点（假设当前线条有下一条相连线条）
    if (linesData[currentLineIndex].nextLine) {
        let nextLine = linesData[currentLineIndex].nextLine;
        nextLine.startPoint = newEndPoint.clone();

        // 更新下一个线条的几何体坐标（假设下一个线条的更新函数与当前线条类似）
        let nextLineVertices = new Float32Array([
            nextLine.startPoint.x, nextLine.startPoint.y, nextLine.startPoint.z,
            nextLine.endPoint.x, nextLine.endPoint.y, nextLine.endPoint.z
        ]);
        nextLine.geometry.setAttribute('position', new THREE.BufferAttribute(nextLineVertices, 3));
    }

    // 重新渲染场景以显示更新后的线条
    renderer.render(scene, camera);
}

// 绑定keyup事件监听器并获取输入值来更新线条
function bindKeyupEventListener(sname) {
    // 获取键盘元素
    let num = ''
    Bus.subscribe((item) => {
        num = item / window.innerWidth * 2 - 1;
        // 更新线条的终点坐标并重新渲染线条
        updateLineEndPoint(sname, num);
        // 重新绑定keyup事件监听器并获取输入值来更新线条
        bindKeyupEventListener(sname);

    })
}

// 渲染循环
function animate() {
    requestAnimationFrame(animate);
    renderer.render(scene, camera);
}

// 绑定触摸事件监听器
document.addEventListener('touchstart', handleTouchStart, { passive: false });

// 启动渲染循环
animate();

// 在页面卸载时，移除事件监听器
window.addEventListener('unload', () => {
    document.removeEventListener('touchstart', handleTouchStart);
    if (keyupEventListener) {
        document.removeEventListener('keyup', keyupEventListener);
    }
});

// // 添加名称
// Bus.subscribe((item) => {
//     const canvas = renderer.domElement;
//     canvas.addEventListener('click', () => {
//         const name = item;
//     })
// })